export default class MSocket {
    constructor(config) {
      if (!config.url) {
        throw new Error('websocket url is invalid');
      }
      this.reconnectTimer = null;
      this.heartbeatTimer = null;
      this.isAlive = false; // 是否已经链接
      this.config = {
        url: '', // 链接路径
        // retry: Infinity, // 重连次数
        retry: 10, // 重连次数
        reconnectWait: 5 * 1000, // 重连间隔时间
        heartBeatWait: 10 * 1000, // 心跳包发送间隔时间
        heartMsg: 'test', // 心跳包发送数据
        isHeartBeat: true // 是否开启心跳包
      };
      Object.keys(config).forEach(key => {
        this.config[key] = config[key]
      });
      this.init();
    }
  
    init() {
      this.socket = new WebSocket(this.config.url);
  
      this.socket.onerror = (e) => {
        this.reconnect();
        this.isAlive = false;
        clearInterval(this.config.heartbeatTimer);
        typeof this.config.onerror === 'function' && this.config.onerror(e);
      };
  
      this.socket.onmessage = ({ data }) => {
        const res = data.indexOf('{') > -1 ? JSON.parse(data) : data;
        typeof this.config.onmessage === 'function' && this.config.onmessage(res);
      }
  
      this.socket.onclose = (e) => {
        this.isAlive = false;
        clearInterval(this.config.heartbeatTimer);
        console.info('websocket was closed');
        typeof this.config.onclose === 'function' && this.config.onclose(e);
      }
  
      this.socket.onopen = (e) => {
        console.info('websocket was opened');
        this.isAlive = true;
        if (this.config.isHeartBeat) {
          this.startHeart();
        }
        typeof this.config.onopen === 'function' && this.config.onopen(e);
      }
    }
  
    // 发送数据
    send(data) {
      if (!this.isAlive) return
      const text = typeof data === 'string' ? data : JSON.stringify(data)
      this.socket.send(text)
    }
  
    // 关闭链接
    close() {
      this.isAlive = false;
      this.socket && this.socket.close();
    }
  
    // 自动重连
    reconnect() {
      this.reconnectTimer = setTimeout(() => {
        if (this.config.retry > 0) {
          this.config.retry--
          this.init()
        }
      }, this.config.reconnectWait)
    }
  
    // 自动心跳包
    startHeart() {
      this.heartbeatTimer = setInterval(() => {
        this.send(this.config.heartMsg)
      }, this.config.heartBeatWait)
    }
  }
  